import datetime
import numbers

pass    # todo ####################################################################    多继承
# 深度优先   “菱形”继承
# class E:
#     pass
# class D:
#     pass
# class C(E):
#     pass
# class B(D):
#     pass
# class A(B, C):
#     pass
# # __mro__ 查询类的调用顺序
# print(A.__mro__)

# 广度优先
# class D:
#     pass
# class C(D):
#     pass
# class B(D):
#     pass
# class A(B, C):
#     pass
# # C3算法
# print(A.__mro__)
pass    # todo ####################################################################    class_method
# """
# # 实例方法：带有参数的实例函数
# # 静态方法: 使用类名，不能改名字          静态方法是个独立的、单纯的函数，它仅仅托管于某个类的名称空间中，便于使用和维护
# # 类方法：指向调用类     模拟java中多构造函数
# # 抽象方法: 抽象方法表示基类的一个方法，没有实现，所以基类不能实例化，子类实现了该抽象方法才能被实例化
#
# 静态方法 属于 类的 工具函数
# 类方法 属于 类的 公共函数
# 实例方法 属于 类的 私有函数
#
#
# 子类的实例继承了父类的static_method静态方法，调用该方法，还是调用的父类的方法和类属性。
# 子类的实例继承了父类的class_method类方法，调用该方法，调用的是子类的方法和子类的类属性。
# """
# class Date:
#     def __init__(self, y, m, d):
#         self.y = y
#         self.m = m
#         self.d = d
#
#     # 实例方法
#     def __str__(self):
#         return F"{self.y}/{self.m}/{self.d}"
#
#     @staticmethod
#     def test(data_str):
#         print(data_str)
#
#     # 静态方法
#     @staticmethod
#     def parse_from_str(data_str):
#         return Date.test(data_str)
#
#     # 类方法
#     @classmethod
#     def parse_str(cls, data_str):
#         return cls.test(data_str)
#
#
# class Data_1(Date):
#
#     @staticmethod
#     def test(data_str):
#         print(data_str, 1)
#
#
# if __name__ == '__main__':
#     # data = Date('2023', '11', '8')
#     # print(data)
#     #
#     # data_str = "2023-11-08"
#     # y, m, d = tuple(data_str.split("-"))
#     # print(y, m, d)
#     #
#     # data = Date(y, m, d)
#     # print(data)
#     #
#     # # 静态方法调用
#     # new_data = Date.parse_from_str(data_str)
#     # print(new_data)
#     #
#     # # 类方法
#     # new_data = Date.parse_from_str(data_str)
#     # print(new_data)
#
#     print(Data_1.parse_from_str("2023-11-8"))
#     print(Data_1.parse_str("2023-11-8"))
pass    # todo ####################################################################    私有属性 与 封装
# class Date:
#     def __init__(self, y, m, d):
#         self.y = y
#         self.m = m
#         self.d = d
#
#     def __str__(self):
#         return F"{self.y}/{self.m}/{self.d}"
#
#     @staticmethod
#     def test(data_str):
#         print(data_str)
#
#     @staticmethod
#     def parse_from_str(data_str):
#         return Date.test(data_str)
#
#     @classmethod
#     def parse_str(cls, data_str):
#         return cls.test(data_str)
#
#
# class User:
#     """
#         __ 私有属性
#     """
#     def __init__(self, b):
#         self.__b = b
#
#     def agg_get(self):
#         return 2023 - int(self.__b.y)
#
#
# if __name__ == '__main__':
#     user = User(Date('2022', '11', '8'))
#     print(user._User__b)   # 外部访问私有属性
#     print(user._User__b, user.agg_get())
pass    # todo ####################################################################    自省, super函数
# class Person:
#     name = "user"
#
# class Student(Person):
#
#     def __init__(self, scool_name):
#         self.scool_name = scool_name
#
#
# if __name__ == '__main__':
#     user = Student('534')
#
#     print(user.__dict__, "\n", Person.__dict__, "\n", dir(user))

#
# class A:
#     def __init__(self):
#         print('A')
#
#
# class B(A):
#     def __init__(self):
#         print('B')
#         super().__init__()
#
#
# class C(A):
#     def __init__(self):
#         print('C')
#         super().__init__()
#
#
# class D(B, C):
#     def __init__(self):
#         print('D')
#         super().__init__()


# from threading import Thread
#
#
# class MyThread(Thread):
#     def __init__(self, name, user):
#         self.user = user
#         super().__init__(name=name)
#
#
# if __name__ == '__main__':
#     b = D()
#     print(b, "\n", D.__mro__)
pass    # todo ####################################################################    多继承 与 mixin 编程模式
# """
# 1. mixin 编程模式: 实现了某种功能单元的类，用于被其他子类继承，将功能组合到子类中。
#     利用 Python 的多重继承，子类可以继承不同功能的 Mixin 类，按需动态组合使用。
#     当多个类都实现了同一种功能时，这时应该考虑将该功能抽离成 Mixin 类。
# 2. mixin 功能单一
# 3. 不和基类关联, 可以和任意基类组合。 基类可以不和mixin 关联就能初始化成功
# 4. 在mixin中不要使用super这种用法
# """
# # map mixin
# class MappingMixin:
#     # 返回所给键对应的值
#     def __getitem__(self, key):
#         return self.__dict__[key]
#
#     def __setitem__(self, key, value):
#         return self.__dict__.set(key, value)
#
# # repr mixin
# class ReprMixin:
#     # 定义了实例化对象的输出信息，重写该方法，可以输出我们想要的信息，对类的实例化对象有更好的了解。
#     def __repr__(self):
#         s = self.__class__.__name__ + '('
#         for k, v in self.__dict__.items():
#             if not k.startswith('_'):
#                 s += '{}={}, '.format(k, v)
#         s = s.rstrip(', ') + ')'  # 将最后一个逗号和空格换成括号
#         return s
#
# # base class
# class Person:
#     def __init__(self, name, gender, age):
#         self.name = name
#         self.gender = gender
#         self.age = age
#
#
# class Person1(MappingMixin, ReprMixin):
#     def __init__(self, name, gender, age):
#         self.name = name
#         self.gender = gender
#         self.age = age
#
#
# if __name__ == '__main__':
#     p = Person('1', "2", "3")
#     print(p.age)
#
#     p1 = Person1('1', "2", "3")
#     print(p1["age"], "\n", p1)

# """
# self.method() 将会先在当前类中查看 method() 方法，
# 如果没有，就在继承链中进行查找，查找顺序就是你继承的顺序从左到右，
# 直到 method() 方法被找到。
# super().method() 与 self.method() 是差不多的，
# 只是 super().method() 需要跳过当前类而已。
# """
# class Displayer():
#     def display(self, message):
#         print(message)
#
#
# class LoggerMixin():
#     def log(self, message, filename='logfile.txt'):
#         with open(filename, 'a') as fh:
#             fh.write(message)
#
#     def display(self, message):
#         super().display(message)
#         self.log(message)
#
#
# class MySubClass(LoggerMixin, Displayer):
#     def log(self, message):
#         super().log(message, filename='subclasslog.txt')
#
#
# subclass = MySubClass()
# subclass.display("This string will be shown and logged in subclasslog.txt")
# # print(MySubClass.__mro__)
pass    # todo ####################################################################    异常处理、上下文管理器（ contextlib模块 ）
# try:
#     print("21231")
#     raise KeyError
# except KeyError as e:
#     print(e, 45646546)
# finally:
#     print("finally")
#
# with open("1.txt", 'a') as f:
#     f.write('4156')
#     f.close()
pass    # todo ####################################################################    序列类
# 切片
# a = [5, 6, 46, 45, 3, 6, 1, 5, 6, 1, 3, 1, 4]
# a[::2] = [4, 56, 56, 62, 3, 9, 1]
# print(a)

# 数组
# import array
# a = array.array("i")
# a.append(1)

# # 列表生成式  性能高于列表操作
# a = [i for i in [1, 1, 2, 2, 3]]

# # 生成器表达式
# a = (i for i in [1, 1, 2, 2, 3])
# print(type(a), a, list(a))

# # 字典推导式
# my_dict = {"a": 1, "b": 2, "c": 3}
# reversed_dict = {value: key for key, value in my_dict.items()}
# print(reversed_dict)

# # 集合推导式
# my_set = {key for key, value in my_dict.items()}
# my_set1 = set(my_dict.keys())
# print(type(my_set), type(my_set1))

# # dict
# """
# dict 属于mapping类型
#
# .copy()  浅拷贝
#
# import copy
# copy.deepcopy(a) 深拷贝
# """
# from collections.abc import Mapping, MutableMapping
# a = {}
# print(isinstance(a, Mapping))
# from collections import UserDict, defaultdict

# # set
# """
# 不重复的无序集合
# frozenset
# """
# s = set("1")
# s1 = {"1", "2"}
# print(s, s1, type(s1))
#
# s2 = frozenset("abjhhjggggg")
# print(s2, type(s2))
pass    # todo ####################################################################    变量
"""
python 变量本质上是一个指针 int str
del语句
垃圾回收：引用计数， 计数器为0时回收
"""
pass    # todo ####################################################################    元类编程
"""
@property  动态属性
__getattr__ 找不到属性时调用对象的魔法函数
__getattribute__ 是否找到都会调用
属性描述符

魔法函数 __new__  与 __init__ 的区别：
    new: 用来控制对象的生成过程，在对象生成之前
    init: 用来完善对象的
    如果new方法不返回对象，则不会调用init函数
"""
# from datetime import date
# import numbers
#
# 实现一种方法就是属性描述符
# class IntField:
#
#     def __get__(self, instance, owner):
#         return self.value
#
#     def __set__(self, instance, value):
#         if not isinstance(value, numbers.Integral):
#             raise ValueError("需要int类型")
#         if value < 0:
#             raise ValueError("输入正确的数据类型")
#         self.value = value
#
#     def __delete__(self, instance):
#         pass
#
#
# class User:
#     age = IntField()
#
#     def __init__(self, name, birthday):
#         self.name = name
#         self.birthday = birthday
#         self._age = 0
#
#     # def get_age(self):
#     #     return datetime.datetime.now().year - self.birthday.year
#
#     @property
#     def age(self):
#         return self._age
#
#     @age.setter
#     def age(self, value):
#         self._age = value
#
#     # 找不到属性时调用对象的魔法函数
#     def __getattr__(self, item):
#         return "属性名字, {}, ".format(item)
#
#     def __getattribute__(self, item):
#         return "属性名字2423432523432, {}".format(item)
#
# if __name__ == '__main__':
#     # user = User('1', date(year=1994, month=1, day=1))
#     # user.age = 30
#     # print(user.age)
#     # print(user.age12)
#     # print(user.birthday)
#
#     user = User()
#     user.age = 12
#     print(user.age)
"""
元类 
"""
# def create_class(name):
#     if name == '1':
#         class User:
#             def __str__(self):
#                 return "user"
#         return User
#     elif name == "2":
#         class Company:
#             def __str__(self):
#                 return "Company"
#         return Company
#
#
# def say(self):
#     return "545454"
#
# # 基类
# class BaseClass:
#     def answer(self):
#         return "afsdfsdfsdfsfs"
#
# if __name__ == '__main__':
#     # my_class = create_class('1')
#     # obj = my_class()
#     # print(obj)
#
#     # type 动态创建类
#     User = type("User", (BaseClass, ), {"u": "user", 'say': say})
#     obj = User()
#     print(obj.say(), obj.answer())
"""
    ORM
"""
# # 属性描述符
# class CharField:
#     def __init__(self, db_column, max_length):
#         self.db_column = db_column
#         self.max_length = max_length
#
#     def __get__(self, instance, owner):
#         return self.value
#
#     def __set__(self, instance, value):
#         if not isinstance(value, numbers.Integral):
#             raise ValueError("需要int类型")
#         if value < 0:
#             raise ValueError("输入正确的数据类型")
#         self.value = value
#
# class IntField:
#     def __init__(self, min_value):
#         self.min_value = min_value
#
#     def __get__(self, instance, owner):
#         return self.value
#
#     def __set__(self, instance, value):
#         if not isinstance(value, numbers.Integral):
#             raise ValueError("需要int类型")
#         if value < 0:
#             raise ValueError("输入正确的数据类型")
#         self.value = value
#
# class ModelMetaClass(type):
#     def __new__(cls, name, bases, attrs, **kwargs):
#         for k, v in attrs.items():
#             pass
#
# class BaseModel(metaclass=ModelMetaClass):
#     def __init__(self, *args, **kwargs):
#         for k, v in kwargs.items():
#             setattr(self, k, v)
#         return super().__init__()
#
#     def save(self):
#         pass
#
# class User(BaseModel):
#     name = CharField(db_column="", max_length=10)
#     age = IntField(min_value=0)
pass    # todo ####################################################################    迭代器与生成器
"""
可迭代的对象
迭代器：访问集合类元素的一种方式，一般用来便利数组的
    与下标的访问方式不一样，迭代器是不能返回的，迭代器提供了一种惰性方式数据的方式
"""
# from collections.abc import Iterator, Iterable
#
# a = [1, 2]
# iter_rator = iter(a)
# print(isinstance(a, Iterable))
# print(isinstance(iter_rator, Iterator))
"""
生成器
    1. 生成器函数：存在yield就是生成器函数
    2. 惰性求值，延迟求值提供了可能
"""
def gen_fun():
    yield 1
    yield 2
    yield 3

def func():
    return 1


if __name__ == '__main__':
    gen = gen_fun()
    for v in gen:
        print(v)
    fun = func()

    print(gen, fun)